package com.mingqijia.gassafety.webserver.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.exception.BizException;
import com.mingqijia.gassafety.db.entity.AicallTask;
import com.mingqijia.gassafety.db.mapper.AicallTaskMapper;
import com.mingqijia.gassafety.shared.constant.CallTypeEnum;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.GssBusinessNoticeConstant;
import com.mingqijia.gassafety.webserver.dto.CallTaskDTO;
import com.mingqijia.gassafety.webserver.request.BusinessNoticeRequest;
import com.mingqijia.gassafety.webserver.service.AicallTaskService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 任务池 服务实现类
 * </p>
 *
 * @Author: duanhongxiang
 * @Date: 2024/1/22 18:53
 */
@Service
@Slf4j
public class AicallTaskServiceImpl extends ServiceImpl<AicallTaskMapper, AicallTask> implements AicallTaskService {
    @Autowired
    XFCallServiceImpl xfCallService;

    @Value(value = "${gassafety.xf.call.appKey}")
    public String appKey;

    @Value(value = "${gassafety.xf.call.appSecret}")
    public String appSecret;

    @Value(value = "${gassafety.xf.call.url}")
    public String callServerUrl;

    @Value(value = "${gassafety.xf.call.robotId}")
    public String robotId;

    @Value(value = "${gassafety.xf.call.appId}")
    public Integer appId;

    private static final String voiceCode = "62360";

    @Override
    public void handleAicallTask(BusinessNoticeRequest req, String spId) throws BizException {
        try {
            QueryWrapper<AicallTask> aicallTaskQueryWrapper = new QueryWrapper<>();
            aicallTaskQueryWrapper.lambda().eq(AicallTask::getSpId, spId)
                    .eq(AicallTask::getParamCode, req.getParamCode())
                    .orderByDesc(AicallTask::getCreatedAt);
            List<AicallTask> aicallTasks = this.baseMapper.selectList(aicallTaskQueryWrapper);
            AicallTask aicallTask = null;
            if( aicallTasks.size()>0 ){
                aicallTask = aicallTasks.get(0);
            }
            
            if( !StringUtils.isEmpty(req.getRobotContent()) ){
                String robotContent = req.getRobotContent();
                for(String key:Constants.ROBOT_CONTENT_KEY_MAP.keySet()){
                    robotContent = robotContent.replace(key,Constants.ROBOT_CONTENT_KEY_MAP.get(key));
                }
                req.setRobotContent(robotContent);
            }
            
            Map<String, String> paramCodeAppMap = GssBusinessNoticeConstant.AICALL_PARAM_CODE_APP_PREFIX;
            String appNamePrefix = paramCodeAppMap.get(req.getParamCode());

            if ( null == aicallTask || aicallTask.getTaskCode().contains("_yantai") ) { //创建
                //创建应用，任务池 【基础服务】
                createAppTask(req, spId, appNamePrefix);
                if ( aicallTask != null && aicallTask.getTaskCode().contains("_yantai") ) {
                    aicallTask.setIsDeleted(true);
                    baseMapper.updateById(aicallTask);
                }
            } else if (paramsChangeFlag(req, aicallTask, 0)) { //有变化，更新
                if (paramsChangeFlag(req, aicallTask, 1)) { //appkey,appsecret改变
                    //将t_gss_aicall_task相应记录is_deleted置为1
                    aicallTask.setIsDeleted(true);
                    baseMapper.updateById(aicallTask);
                    //更新应用，任务池 【基础服务】
                    updateAppTask(req, spId, appNamePrefix, aicallTask);
                } else {
                    updateTask(req, aicallTask, appNamePrefix);
                }
                if ( aicallTasks.size()>0 && aicallTasks.get(aicallTasks.size()-1).getTaskCode().contains("_yantai") ) {
                    aicallTasks.get(aicallTasks.size()-1).setIsDeleted(true);
                    baseMapper.updateById(aicallTasks.get(aicallTasks.size()-1));
                }
            }
        }catch(Exception e){
            log.error("error：",e);
            throw new BizException("调用基础服务创建应用或任务失败");
        }
    }

    @Override
    public void updateAicallTask(String paramCode, String spId) {
        AicallTask aicallTask = this.getByParamCode(paramCode, spId);
        if(!ObjectUtils.isEmpty(aicallTask)){
            baseMapper.updateIsDeletedById(aicallTask.getId());
        }
        
        QueryWrapper<AicallTask> aicallTaskQueryWrapper = new QueryWrapper<>();
        aicallTaskQueryWrapper.lambda().eq(AicallTask::getSpId, spId)
                .eq(AicallTask::getParamCode, paramCode)
                .orderByAsc(AicallTask::getCreatedAt);
        List<AicallTask> aicallTasks = this.baseMapper.selectList(aicallTaskQueryWrapper);
        AicallTask aicallTask1 = aicallTasks.get(0);
        if ( aicallTask1.getTaskCode().contains("_yantai") ) {
            aicallTask1.setIsDeleted(false);
            baseMapper.updateById(aicallTask1);
        }
    }

    /**
     * 更新应用的task
     *
     * @param req
     * @param aicallTask
     * @param appNamePrefix
     * @throws BizException
     */
    private void updateTask(BusinessNoticeRequest req, AicallTask aicallTask, String appNamePrefix) throws BizException {
        if (StringUtils.isEmpty(appNamePrefix)) {
            throw new BizException("找不到应用名称");
        }
        String taskCodeKey = appNamePrefix + "_task";
        CallTypeEnum callTypeEnum = CallTypeEnum.getPushTypesByTaskCode(taskCodeKey);
        //任务池更新 【基础服务】
        CallTaskDTO callTaskDTO = new CallTaskDTO();
        callTaskDTO.setAppId(aicallTask.getAppId());
        callTaskDTO.setId(aicallTask.getTaskpoolId());
        callTaskDTO.setTaskCode(aicallTask.getTaskCode());
        callTaskDTO.setTaskName(aicallTask.getTaskName());
        callTaskDTO.setOrgCode(aicallTask.getOrgCode());
        callTaskDTO.setRobotId(req.getRobotId());
        callTaskDTO.setLineNum(req.getLineNum());
        callTaskDTO.setVoiceCode(voiceCode);
        callTaskDTO.setCallColumn(JSONArray.parseArray(callTypeEnum.getCallColumn()));
        xfCallService.taskPoolUpdate(callTaskDTO);
        AicallTask aicallTask1 = new AicallTask();
        aicallTask1.setId(aicallTask.getId());
        aicallTask1.setRobotId(req.getRobotId());
        aicallTask1.setLineNum(req.getLineNum());
        aicallTask1.setVoiceCode(voiceCode);
        aicallTask1.setRobotContent(StringUtils.isEmpty(req.getRobotContent())?"":req.getRobotContent());
        aicallTask1.setIsDeleted(false);
        baseMapper.updateById(aicallTask1);
    }

    /**
     * 创建应用及task
     *
     * @param req
     * @param spId
     * @param appNamePrefix
     */
    private void createAppTask(BusinessNoticeRequest req, String spId, String appNamePrefix) throws BizException{
        if (StringUtils.isEmpty(appNamePrefix)) {
            throw new BizException("找不到应用名称");
        }
        String appName = appNamePrefix+"_"+spId;
        int appId = findXfAppId(appName, req.getAppKey(), req.getAppSecret());
                
        if (appId == 0) {
            JSONObject appResp = xfCallService.appCreate(appName, req.getAppKey(), req.getAppSecret());
            appId = appResp.getInteger("appId");
        }
        //创建任务池 【基础服务】
        String taskCodeKey = appNamePrefix + "_task";
        String taskCode = appNamePrefix + "_task" + "_" + spId;

        CallTypeEnum callTypeEnum = CallTypeEnum.getPushTypesByTaskCode(taskCodeKey);
        
        String orgCode = "gassafety";
        
        CallTaskDTO callTaskDTO = new CallTaskDTO();
        callTaskDTO.setAppId(appId);
        callTaskDTO.setTaskCode(taskCode);
        callTaskDTO.setTaskName(callTypeEnum.getTaskName());
        callTaskDTO.setOrgCode(orgCode);
        callTaskDTO.setRobotId(req.getRobotId());
        callTaskDTO.setLineNum(req.getLineNum());
        callTaskDTO.setVoiceCode(voiceCode);
        callTaskDTO.setCallColumn(JSONArray.parseArray(callTypeEnum.getCallColumn()));
        JSONObject taskResp = xfCallService.tackPoolAdd(callTaskDTO);

        int taskPoolId = taskResp.getInteger("taskPoolId");
        AicallTask aicallTask1 = new AicallTask();
        aicallTask1.setParamCode(req.getParamCode());
        aicallTask1.setTaskCode(taskCode);
        aicallTask1.setAppId(appId);
        aicallTask1.setTaskpoolId(taskPoolId);
        aicallTask1.setOrgCode(orgCode);
        aicallTask1.setAppKey(req.getAppKey());
        aicallTask1.setAppSecret(req.getAppSecret());
        aicallTask1.setTaskName(callTypeEnum.getTaskName());
        aicallTask1.setRobotId(req.getRobotId());
        aicallTask1.setRobotContent(req.getRobotContent());
        if( StringUtils.isEmpty(req.getRobotContent()) && 
                Constants.ROBOT_ID_FORAN.equals(req.getRobotId()) ){
            aicallTask1.setRobotContent(Constants.ROBOT_ID_20041321);
        }
        aicallTask1.setLineNum(req.getLineNum());
        aicallTask1.setVoiceCode(voiceCode);
        aicallTask1.setSpId(spId);
        baseMapper.insert(aicallTask1);
    }

    /**
     * 更新应用及任务池
     * @param req
     * @param spId
     * @param appNamePrefix
     * @param aicallTask
     * @throws BizException
     */
    private void updateAppTask(BusinessNoticeRequest req, String spId, String appNamePrefix,AicallTask aicallTask) throws BizException{
        if (StringUtils.isEmpty(appNamePrefix)) {
            throw new BizException("找不到应用名称");
        }
        String appName = appNamePrefix+"_"+spId;
        
        int appId = findXfAppIdByAppName(appName);

        if (appId == 0) {
            JSONObject appResp = xfCallService.appCreate(appName, req.getAppKey(), req.getAppSecret());
            appId = appResp.getInteger("appId");
        }else{
            xfCallService.appUpdate(appName, appId, req.getAppKey(), req.getAppSecret());
        }
        //更新任务池 【基础服务】
        String taskCodeKey = appNamePrefix + "_task";
        CallTypeEnum callTypeEnum = CallTypeEnum.getPushTypesByTaskCode(taskCodeKey);
        //任务池更新 【基础服务】
        CallTaskDTO callTaskDTO = new CallTaskDTO();
        callTaskDTO.setAppId(aicallTask.getAppId());
        callTaskDTO.setId(aicallTask.getTaskpoolId());
        callTaskDTO.setTaskCode(aicallTask.getTaskCode());
        callTaskDTO.setTaskName(aicallTask.getTaskName());
        callTaskDTO.setOrgCode(aicallTask.getOrgCode());
        callTaskDTO.setRobotId(req.getRobotId());
        callTaskDTO.setLineNum(req.getLineNum());
        callTaskDTO.setVoiceCode(voiceCode);
        callTaskDTO.setCallColumn(JSONArray.parseArray(callTypeEnum.getCallColumn()));
        xfCallService.taskPoolUpdate(callTaskDTO);
        int taskPoolId = aicallTask.getTaskpoolId();
        AicallTask aicallTask1 = new AicallTask();
        aicallTask1.setParamCode(req.getParamCode());
        aicallTask1.setTaskCode(aicallTask.getTaskCode());
        aicallTask1.setAppId(appId);
        aicallTask1.setTaskpoolId(taskPoolId);
        aicallTask1.setOrgCode(aicallTask.getOrgCode());
        aicallTask1.setAppKey(req.getAppKey());
        aicallTask1.setAppSecret(req.getAppSecret());
        aicallTask1.setTaskName(callTypeEnum.getTaskName());
        aicallTask1.setRobotId(req.getRobotId());
        aicallTask1.setRobotContent(req.getRobotContent());
        if( StringUtils.isEmpty(req.getRobotContent()) &&
                Constants.ROBOT_ID_FORAN.equals(req.getRobotId()) ){
            aicallTask1.setRobotContent(Constants.ROBOT_ID_20041321);
        }
        aicallTask1.setLineNum(req.getLineNum());
        aicallTask1.setVoiceCode(voiceCode);
        aicallTask1.setSpId(spId);
        baseMapper.insert(aicallTask1);
    }

    /**
     * 查找基础服务相应的appid
     *
     * @param appName
     * @param appKey
     * @param appSecret
     * @return
     * @throws BizException
     */
    public int findXfAppId(String appName, String appKey, String appSecret) throws BizException {
        JSONObject resp = xfCallService.appSearch(appName);
        if (resp == null) {
            throw new BizException("查找应用信息失败");
        }
        JSONArray jsonArray = resp.getJSONArray("list");
        int appId = 0;
        if ( jsonArray.size() > 0 ){
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                jsonObject.getString("key");
                jsonObject.getString("secret");
                if (appKey.equals(jsonObject.getString("key")) && 
                        appSecret.equals(jsonObject.getString("secret"))) {
                    appId = jsonObject.getInteger("id");
                    break;
                }
            }
            if( appId == 0 ){
                appId = jsonArray.getJSONObject(0).getInteger("id");
                //更新应用信息
                xfCallService.appUpdate(appName, appId, appKey, appSecret);
            }
        }
        return appId;
    }

    /**
     * 查找基础服务相应的appid
     *
     * @param appName
     * @return
     * @throws BizException
     */
    public int findXfAppIdByAppName(String appName) throws BizException {
        JSONObject resp = xfCallService.appSearch(appName);
        if (resp == null) {
            throw new BizException("查找应用信息失败");
        }
        JSONArray jsonArray = resp.getJSONArray("list");
        if( jsonArray.size() > 0 ){
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            return jsonObject.getInteger("id");
        }
        return 0;
    }

    /**
     * 参数修改标识 true 为已修改，false 未修改
     *
     * @param req
     * @param aicallTask
     * @return
     */
    private boolean paramsChangeFlag(BusinessNoticeRequest req, AicallTask aicallTask, int type) {
        if( aicallTask.getIsDeleted() ){
            return true;
        }
        boolean flag = false;
        switch (type) {
            case 0:
                flag = !(aicallTask.getAppKey().equals(req.getAppKey()) &&
                        aicallTask.getAppSecret().equals(req.getAppSecret()) &&
                        aicallTask.getRobotId().equals(req.getRobotId()) &&
                        aicallTask.getLineNum().equals(req.getLineNum()) &&
                        aicallTask.getRobotContent().equals(req.getRobotContent()));
                break;
            case 1:
                flag = !(aicallTask.getAppKey().equals(req.getAppKey()) &&
                        aicallTask.getAppSecret().equals(req.getAppSecret()));
                break;
            default:
                System.out.println("type不匹配");
        }
        return flag;
    }

    @Override
    public AicallTask getByParamCode(String paramCode, String spId) {
        Map<String, Object> cond = new HashMap<>();
        cond.put("paramCode", paramCode);
        cond.put("spId", spId);
        List<AicallTask> aicallTasks = baseMapper.findAiCallTask(cond);
        if (null == aicallTasks || aicallTasks.size() == 0) {
            return null;
        }
        return aicallTasks.get(0);
    }

    @Override
    public CallTaskDTO getAicallTaskByParamCode(String paramCode, String spId) {
        log.info("外呼配置：paramCode:{},spId:{}", paramCode, spId);
        CallTaskDTO callTaskDTO = new CallTaskDTO();
        AicallTask aicallTask = this.getByParamCode(paramCode, spId);
        String taskCode = GssBusinessNoticeConstant.AICALL_PARAM_CODE_TASK_CODE_MAP.get(paramCode);
        if (StringUtils.isEmpty(taskCode)) {
            log.info("外呼配置：taskCode 为空");
            return null;
        }
        CallTypeEnum callTypeEnum = CallTypeEnum.getPushTypesByTaskCode(taskCode);
        if (null == callTypeEnum) {
            log.info("外呼配置：taskCode：{}，callTypeEnum为空", taskCode);
            return null;
        }
        if (null == aicallTask) {
            if( 99 == callTypeEnum.getCode() ){ //外呼机器人特殊规则，需要取apollo配置的appId
                callTaskDTO.setAppId(appId);
            }else{
                callTaskDTO.setAppId(callTypeEnum.getAppId());
            }
            callTaskDTO.setTaskCode(callTypeEnum.getTaskCode());
            callTaskDTO.setRobotContent("");
        }else{
            callTaskDTO.setAppId(aicallTask.getAppId());
            callTaskDTO.setTaskCode(aicallTask.getTaskCode());
            callTaskDTO.setRobotContent(StringUtils.isEmpty(aicallTask.getRobotContent())?"":aicallTask.getRobotContent());
        }
        callTaskDTO.setCallColumn(JSONArray.parseArray(callTypeEnum.getCallColumn()));
        log.info("外呼配置：{}", JSON.toJSONString(callTaskDTO));
        return callTaskDTO;
    }


    @Override
    public CallTaskDTO getAicallTaskByType(Integer type, String spId) {
        String paramCode = "";
        if (null == type) {//null 机器人报警
            paramCode = GssBusinessNoticeConstant.OUTBOUND_CUSTOM_ALERT_PARAM_CODE;
        }else{
            switch (type){
                case 0: //设备离线
                    paramCode = GssBusinessNoticeConstant.OUTBOUND_CUSTOM_OFFLINE_PARAM_CODE;
                    break;
                case 1: //设备故障
                    paramCode = GssBusinessNoticeConstant.OUTBOUND_CUSTOM_BROKEN_PARAM_CODE;
                    break;
                case 2: //设备运行报告
                    paramCode = GssBusinessNoticeConstant.OUTBOUND_CUSTOM_RUN_PARAM_CODE;
                    break;
                case 3: // 服务到期
                    paramCode = GssBusinessNoticeConstant.OUTBOUND_CUSTOM_SERVICE_PARAM_CODE;
                    break;
                default:
            }
        }
        if( StringUtils.isEmpty(paramCode) ){
            return null;
        }
        return this.getAicallTaskByParamCode(paramCode, spId);
    }
}
